/**
 * 
 */
package com.leoj.utils.tcp_network;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

/**
 * @author leoj
 *
 */
public abstract class TcpServerSocketThread extends Thread {
	private ServerSocket _server;
	private boolean _running;
	protected ApplicationProtocolFactory _protocolFactory;
	/**
	 * @throws IOException 
	 * 
	 */
	public TcpServerSocketThread(int port, int timeout, ApplicationProtocolFactory factory) throws IOException {
		_server = new ServerSocket(port);
		_server.setSoTimeout(timeout);
		_protocolFactory = factory;
	}
	public TcpServerSocketThread(int port, ApplicationProtocolFactory factory) throws IOException {
		this(port, 3000, factory);
	}
	/* (non-Javadoc)
	 * @see java.lang.Thread#run()
	 */
	@Override
	public final void run() {
		_running = true;
//		System.out.println("starting the server thread : server bound ? -> "+_server.isBound());
		while(_running){
			try {
//				System.out.println("server waiting for incoming connection ");
				handleNewConnection(_server.accept());
//				System.out.println("connection handled !");
			} catch (SocketTimeoutException e){
//				System.out.println("server timeout reached ... ");
			}catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void stopAsap(){
		_running = false;
	}
	
	protected abstract void handleNewConnection(Socket s);
	
	public InetAddress getServerAddress() throws UnknownHostException{
		return InetAddress.getLocalHost();
	}
	public String getServerStrAddress(){
		try {
//			System.out.println("there is/are "+getServerAddress().getAddress().length+" address/es");
//			System.out.println("canonical host : "+getServerAddress().getCanonicalHostName());
//			System.out.println("host address "+getServerAddress().getHostAddress());
//			System.out.println("toString "+getServerAddress().toString());
//			System.out.println(""+getServerAddress());
//			
//			try {
//				Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
//				for(NetworkInterface ni : Collections.list(nets)){
//					if(ni.isLoopback()){
//						System.out.println("loopbackfound");
//					}else{
//						System.out.println("good one found !");
//						Enumeration<InetAddress> addresses = ni.getInetAddresses();
//						for(InetAddress ad : Collections.list(addresses)){
//							System.out.println(ad.toString());
//						}
//					}
//				}
//			} catch (SocketException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
			return this.getServerAddress().getHostAddress();
		} catch (UnknownHostException e) {
			e.printStackTrace();
			return "UNKNOWN_HOST";
		}
	}
	public int getServerPort(){
		return _server.getLocalPort();
	}
}
